package com.stable.actor.network;

import com.stable.actor.core.ActorSystem;

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

/**
 * 生产级网络客户端 - 支持TCP协议
 */
public class NetworkClient {
    private static final ConcurrentMap<String, TcpConnectionPool> connectionPools = new ConcurrentHashMap<>();
    private static volatile boolean initialized = false;
    private static ActorSystem actorSystem;
    /**
     * 初始化NetworkClient
     */
    public static void initialize(ActorSystem system) {
        if (initialized) {
            System.out.println("⚠️ NetworkClient已经初始化过");
            return;
        }

        actorSystem = system;
        initialized = true;
        System.out.println("✅ NetworkClient初始化完成");
    }

    /**
     * 检查是否已初始化
     */
    private static void checkInitialized() {
        if (!initialized || actorSystem == null) {
            throw new IllegalStateException("NetworkClient未初始化，请先调用NetworkClient.initialize(system)");
        }
    }

    /**
     * 发送远程消息 - TCP协议
     */
    public static void send(String host, int port, String path, Object message, String senderPath) {
        checkInitialized();
        String poolKey = host + ":" + port;

        try {
            // 获取或创建连接池
            TcpConnectionPool pool = connectionPools.computeIfAbsent(poolKey,
                    k -> new TcpConnectionPool(host, port));

            // 发送消息
            byte[] response = pool.sendSync(serializeMessage(message, senderPath, path));

            // 处理响应（可选，根据业务需求）
            handleResponse(response);

        } catch (Exception e) {
            System.err.println("❌ 发送远程消息失败: " + e.getMessage());
            // 这里可以添加重试逻辑
        }
    }

    /**
     * 异步发送
     */
    public static CompletableFuture<Void> sendAsync(String host, int port, String path,
                                                    Object message, String senderPath) {
        return CompletableFuture.runAsync(() -> {
            send(host, port, path, message, senderPath);
        });
    }

    private static byte[] serializeMessage(Object message, String senderPath, String targetPath) {
        // 构建协议消息
        ProtocolMessage protocolMsg = new ProtocolMessage();
        protocolMsg.setSenderPath(senderPath);
        protocolMsg.setTargetPath(targetPath);
        protocolMsg.setPayload(message);
        protocolMsg.setTimestamp(System.currentTimeMillis());
        protocolMsg.setMessageId(generateMessageId());

        // 序列化
        return MessageCodec.encode(protocolMsg);
    }

    private static void handleResponse(byte[] response) {
        if (response != null && response.length > 0) {
            try {
                ProtocolMessage responseMsg = MessageCodec.decode(response);
                // 这里可以将响应路由回原来的sender
                routeResponseToActor(responseMsg);
            } catch (Exception e) {
                System.err.println("❌ 处理响应失败: " + e.getMessage());
            }
        }
    }

    private static void routeResponseToActor(ProtocolMessage responseMsg) {
        // 根据senderPath将响应发送回对应的Actor
        String originalSenderPath = responseMsg.getSenderPath();
        if (originalSenderPath != null && !"no-sender".equals(originalSenderPath)) {
            // 这里需要ActorSystem的路由能力
            ActorSystem.routeMessage(originalSenderPath, responseMsg.getPayload());
        }
    }

    private static String generateMessageId() {
        return "msg_" + System.currentTimeMillis() + "_" + ThreadLocalRandom.current().nextInt(1000);
    }

    /**
     * 关闭所有连接池
     */
    public static void shutdown() {
        for (TcpConnectionPool pool : connectionPools.values()) {
            pool.shutdown();
        }
        connectionPools.clear();
    }
    /**
     * 增强的发送方法 - 支持路由响应
     */
//    public static void sendWithResponseRouting(String host, int port, String path,
//                                               Object message, String senderPath) {
//        try {
//            byte[] response = // ... 发送逻辑
//
//            if (response != null) {
//                ProtocolMessage responseMsg = MessageCodec.decode(response);
//                // 自动路由响应回原始发送者
//                ActorSystem.routeMessage(responseMsg.getSenderPath(), responseMsg.getPayload());
//            }
//        } catch (Exception e) {
//            System.err.println("❌ 发送消息失败: " + e.getMessage());
//        }
//    }
}
